﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;

namespace RigLib
{
    public class ProdUiNative
    {
        /// <summary>
        /// Cascades the specified child windows of the specified parent window.
        /// </summary>
        /// <param name="windowHandleParent">A Handle to the window containing the control. If this parameter is NULL, the desktop window is assumed.</param>
        /// <param name="wHow">A cascade flag. This parameter can be one or more of the values from the ArrangeStyle enumeration</param>
        /// <param name="lpRect">A pointer to a structure that specifies the rectangular area, in client coordinates, within which the windows are arranged. This parameter can be NULL, in which case the client area of the parent window is used</param>
        /// <param name="cKids">AThe number of elements in the array specified by the lpKids parameter. This parameter is ignored if lpKids is NULL</param>
        /// <param name="lpKids">An array of handles to the child windows to arrange</param>
        /// <returns>If the function succeeds, the return value is the number of windows arranged</returns>
        /// <remarks>Note: For now, we're using this for ALL windows (desktop as parent)
        /// So...using managed (nullable) rectangle instead of RECT struct</remarks>
        [DllImport("user32.dll", SetLastError = true)]
        internal static extern long CascadeWindows(
            IntPtr windowHandleParent,
            uint wHow,
            Rectangle? lpRect,
            uint cKids,
            IntPtr lpKids
            );

        /// <summary>
        ///   Destroys the specified window. The function sends WM_DESTROY and WM_NCDESTROY messages
        ///   to the window to deactivate it and remove the keyboard focus from it
        /// </summary>
        /// <param name = "windowHandle">A handle to the window to be destroyed</param>
        /// <returns>If the function succeeds, the return value is nonzero</returns>
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool DestroyWindow(
            IntPtr windowHandle
            );

        /// <summary>
        ///   Enumerates the child windows that belong to the specified parent window by passing the handle
        ///   to each child window, in turn, to an application-defined callback function. EnumChildWindows
        ///   continues until the last child window is enumerated or the callback function returns FALSE
        /// </summary>
        /// <param name = "windowHandleParent">A Handle to the window containing the control whose child windows are to be enumerated.
        ///   If this parameter is NULL, this function is equivalent to EnumWindows</param>
        /// <param name = "lpEnumFunc">A pointer to an application-defined callback function</param>
        /// <param name = "lParam">An application-defined value to be passed to the callback function</param>
        /// <returns>The return value is not used.</returns>
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool EnumChildWindows(
            IntPtr windowHandleParent,
            EnumWindowsCallBack lpEnumFunc,
            IntPtr lParam
            );

        /// <summary>
        ///   Enumerates all top-level windows associated with the specified desktop
        /// </summary>
        /// <param name = "hDesktop">Enumerates all top-level windows associated with the specified desktop</param>
        /// <param name = "lpfn">A pointer to an application-defined EnumWindowsProc callback function</param>
        /// <param name = "lParam">An application-defined value to be passed to the callback function</param>
        /// <returns>If the function fails or is unable to perform the enumeration, the return value is zero</returns>
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool EnumDesktopWindows(
            IntPtr hDesktop,
            EnumWindowsCallBack lpfn,
            IntPtr lParam
            );


        /// <summary>
        /// A method to find a window title by class name.
        /// </summary>
        /// <param name="lpClassName">The class name. [Optional]</param>
        /// <param name="lpWindowName">The window title. [Optional]</param>
        /// <returns>First matching Window title.</returns>
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = true, ThrowOnUnmappableChar = true)]
        internal static extern IntPtr FindWindow(
            string lpClassName,
            string lpWindowName
            );

        /// <summary>
        ///   Retrieves a handle to a control in the specified dialog box
        /// </summary>
        /// <param name = "hDlg">A handle to the dialog box that contains the control.</param>
        /// <param name = "nIDDlgItem">The identifier of the control to be retrieved.</param>
        /// <returns>If the function succeeds, the return value is the window handle of the specified control</returns>
        [DllImport("user32.dll", SetLastError = true)]
        internal static extern IntPtr GetDlgItem(
            IntPtr hDlg,
            int nIDDlgItem
            );

        /// <summary>
        ///   Retrieves a handle to the specified window's parent or owner
        /// </summary>
        /// <param name = "windowHandle">A handle to the window whose parent window handle is to be retrieved</param>
        /// <returns>If the window is a child window, the return value is a Handle to the window containing the control.
        ///   If the window is a top-level window with the WS_POPUP style, the return value is a handle to 
        ///   the owner window</returns>
        [DllImport("user32.dll", SetLastError = true)]
        internal static extern IntPtr GetParent(
            IntPtr windowHandle
            );


        /// <summary>
        ///   Copies the text of the specified window's title bar (if it has one) into a buffer
        /// </summary>
        /// <param name = "windowHandle">A handle to the window or control containing the text</param>
        /// <param name = "lpString">The buffer that will receive the text. If the string is as long or longer than the buffer, the string is truncated and terminated with a null character</param>
        /// <param name = "nMaxCount">The maximum number of characters to copy to the buffer, including the null character</param>
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = true,
            ThrowOnUnmappableChar = true)]
        [return: MarshalAs(UnmanagedType.I4)]
        internal static extern int GetWindowText(
            IntPtr windowHandle,
            StringBuilder lpString,
            int nMaxCount
            );

        /// <summary>
        ///   Determines the visibility state of the specified window
        /// </summary>
        /// <param name = "hWnd">A handle to the window to be tested</param>
        /// <returns>If the specified window, its parent window, its parent's parent window, and so forth, have the WS_VISIBLE style, the return value is nonzero. Otherwise, the return value is zero. </returns>
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool IsWindowVisible(
            IntPtr hWnd
            );



        /// <summary>
        /// Retrieves a string that specifies the window type.
        /// </summary>
        /// <param name="windowHandle">A handle to the window whose type will be retrieved</param>
        /// <param name="pszType">A pointer to a string that receives the window type</param>
        /// <param name="cchType">The length, in characters, of the buffer pointed to by the pszType parameter</param>
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = true, ThrowOnUnmappableChar = true)]
        internal static extern void RealGetWindowClass(
            IntPtr windowHandle,
            StringBuilder pszType,
            uint cchType
            );



        /// <summary>
        ///   Brings the thread that created the specified window into the foreground and activates the window.
        ///   Keyboard input is directed to the window, and various visual cues are changed for the user
        /// </summary>
        /// <param name = "windowHandle">A handle to the window that should be activated and brought to the foreground</param>
        /// <returns>If the window was brought to the foreground, the return value is nonzero</returns>
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool SetForegroundWindow(
            IntPtr windowHandle
            );

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = true,
            ThrowOnUnmappableChar = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool SetWindowText(
            IntPtr windowHandle,
            string lpString
            );

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool ShowWindowAsync(
            IntPtr windowHandle,
            int nCmdShow
            );


                /// <summary>
                /// Tiles the specified child windows of the specified parent window
                /// </summary>
                /// <param name="windowHandleParent">A Handle to the window containing the control. If this parameter is NULL, the desktop window is assumed</param>
                /// <param name="wHow">A tiling flag. This parameter can be one or more of the values from the WinArrange enumeration</param>
                /// <param name="lpRect">A pointer to a structure that specifies the rectangular area, in client coordinates, within which the windows are arranged</param>
                /// <param name="cKids">The number of elements in the array specified by the lpKids parameter. This parameter is ignored if lpKids is NULL</param>
                /// <param name="lpKids">An array of handles to the child windows to arrange</param>
                /// <returns>the function succeeds, the return value is the number of windows arranged</returns>
                /// <remarks>Note: For now, we're using this for ALL windows (desktop as parent)
                /// So...using managed (nullable) rectangle instead of RECT struct</remarks>
                [DllImport("user32.dll", SetLastError = true)]
                internal static extern short TileWindows(
                    IntPtr windowHandleParent,
                    uint wHow,
                    Rectangle? lpRect,
                    uint cKids,
                    IntPtr lpKids
                    );


        /// <summary>
        ///   Determines whether the specified window handle identifies an existing window
        /// </summary>
        /// <param name = "hWnd">A handle to the window to be tested</param>
        /// <returns>If the window handle identifies an existing window, the return value is nonzero</returns>
        /// <remarks>
        ///   Handle Recycling: http://blogs.msdn.com/b/oldnewthing/archive/2007/07/17/3903614.aspx
        /// </remarks>
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool IsWindow(
            IntPtr hWnd
            );
    }
}
